package discover

import (
	"context"
	"net"
	"time"

	"github.com/lukeaxu/discover/registry"
	"google.golang.org/grpc"
)

type ServerOpt func(*Server)

type Server struct {
	*grpc.Server
	registry        registry.Registry
	registerTimeout time.Duration
	name            string
}

func WithRegisterTimeout(d time.Duration) ServerOpt {
	return func(s *Server) {
		s.registerTimeout = d
	}
}

func WithRegistry(r registry.Registry) ServerOpt {
	return func(s *Server) {
		s.registry = r
	}
}

func NewServer(name string, opts ...ServerOpt) (*Server, error) {
	server := &Server{
		Server:          grpc.NewServer(),
		name:            name,
		registerTimeout: time.Second * 3,
	}
	for _, opt := range opts {
		opt(server)
	}
	return server, nil
}

func (s *Server) Start(host string) error {
	listen, err := net.Listen("tcp", host)
	if err != nil {
		return err
	}
	for s.registry != nil {
		// Mark: 用户决定注册的等待时长
		// ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
		ctx, cancel := context.WithTimeout(context.Background(), s.registerTimeout)
		defer cancel()
		err := s.registry.Register(ctx, registry.ServiceInstance{
			Name: s.name,
			Addr: listen.Addr().String(),
		})
		if err == nil {
			break
		}
		time.Sleep(time.Second)
	}
	return s.Serve(listen)
}
